using System;
using System.Data;
using Castle.Core.Logging;
using NHibernate;

namespace Caramel.NHibernate
{
	public class NHibernateUnitOfWorkFactory : IUnitOfWorkFactory
	{
		public NHibernateUnitOfWorkFactory(ISessionFactory sessionFactory)
		{
			this.Logger = NullLogger.Instance;
			this.SessionFactory = sessionFactory;
			this.SessionFlushMode = FlushMode.Never;
		}

		public ILogger Logger { get; set; }

		public ISessionFactory SessionFactory { get; private set; }

		public FlushMode SessionFlushMode { get; set; }

		#region IUnitOfWorkFactory Members

		public IUnitOfWork Create(string name, IsolationLevel isolationLevel)
		{
			var session = this.SessionFactory.OpenSession();
			session.FlushMode = this.SessionFlushMode;

			this.Logger.DebugFormat("Creating {0} - {1}...", typeof(NHibernateUnitOfWork).Name, name);

			var work = new NHibernateUnitOfWork(session, name, isolationLevel);

			this.Logger.DebugFormat("Created {0} - {1} - {2}...", typeof(NHibernateUnitOfWork).Name, work.Name, work.ID);

			return work;
		}

		public IUnitOfWork CreateReadOnly(string name, IsolationLevel isolationLevel)
		{
			var session = this.SessionFactory.OpenSession();
			session.FlushMode = FlushMode.Never;

			this.Logger.DebugFormat("Creating {0} - {1}...", typeof(NHibernateReadOnlyUnitOfWork).Name, name);

			var work = new NHibernateReadOnlyUnitOfWork(session, name, isolationLevel);

			this.Logger.DebugFormat("Created {0} - {1} - {2}...", typeof(NHibernateReadOnlyUnitOfWork).Name, work.Name, work.ID);

			return work;
		}

		#endregion
	}
}
